﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace D.UtilCore.WChartUtils
{
    public static class WeChatMiniProgramUtil
    {
        public static string WeChatUrl = "https://api.weixin.qq.com/";
        public static string WeChartHttpClient = "WxClient";

        public static void AddWeChartUtil(this IServiceCollection services)
        {
            services.AddHttpClient(WeChartHttpClient, config =>
            {
                config.BaseAddress = new Uri(WeChatUrl);
                config.DefaultRequestHeaders.Add("Accept", "application/json");
            });
        }

        public static void UseWeChartUtil(this IApplicationBuilder app)
        {
            WeChatMiniProgramUtil.HttpClientFactory = app.ApplicationServices.GetService<IHttpClientFactory>();
        }

        public static IHttpClientFactory HttpClientFactory { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public static DateTime TimeOutDate { get; set; }

        /// <summary>
        /// Token
        /// </summary>
        public static string Token { get; set; }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <returns>Item1 Token;Item2 是否成功</returns>
        public static async Task<Tuple<string, bool>> GetTokenAsync(string appid, string secret)
        {
            //判断Token是否存在 以及Token是否在有效期内
            //if (string.IsNullOrEmpty(Token) || TimeOutDate > DateTime.Now)
            //{
                //构造请求链接
                var requestBuild = $"cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";

                using (var wxClient = HttpClientFactory.CreateClient(WeChartHttpClient))
                {
                    var httpResponse = await wxClient.GetAsync(requestBuild);
                    var result = await httpResponse.Content.ReadAsStringAsync();

                    var dynamic = JsonConvert.DeserializeObject<WeChartToken>(result);
                    if (dynamic.errcode == 0)
                    {
                        Token = dynamic.access_token;

                        //过期5分钟前刷新Token
                        //var expires_in = Convert.ToDouble(dynamic.expires_in - 5 * 60);
                        //TimeOutDate = DateTime.Now.AddSeconds(110);
                        return Tuple.Create(Token, true);
                    }
                    else
                    {
                        return Tuple.Create($"获取Token失败，错误：{dynamic.errmsg}", false);
                    }
                }
            //}
            //else
            //{
            //    return Tuple.Create(Token, true);
            //}
        }

        /// <summary>
        /// 获取手机号
        /// </summary>
        /// <param name="accessToken"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static async Task<Tuple<string, bool>> GetPhoneAsync(string accessToken, string code)
        {
            var url = $"wxa/business/getuserphonenumber?access_token={accessToken}";
            //var content = new StringContent(JsonConvert.SerializeObject(new ReqGetPhone()
            //{
            //    code = code,
            //}), Encoding.UTF8, "application/json");
            var content = new JObject();
            content.Add("code", code);
            using (var wxClient = HttpClientFactory.CreateClient(WeChartHttpClient))
            {

                var httpResponse = await wxClient.PostAsync(url, new StringContent(content.ToString()));
                //var httpResponse = await wxClient.PostAsync(url, content);
                var result = await httpResponse.Content.ReadAsStringAsync();
                var res = JsonConvert.DeserializeObject<RepGetPhone>(result);
                if (res.errcode == 0)
                {
                    return Tuple.Create(res.phone_info.phoneNumber, true);
                }
                else
                {
                    return Tuple.Create($"获取Phone失败，错误：{res.errmsg}", false);
                }
            }
        }
    }

    public class ReqGetPhone
    {
        /// <summary>
        /// 手机号获取凭证
        /// </summary>
        public string code { get; set; }
    }

    public class RepGetPhone
    {
        /// <summary>
        /// 错误码	错误描述        	    解决方案
        /// -1	    system error        系统繁忙，此时请开发者稍候再试
        /// 40029	code 无效           js_code无效
        /// 45011	api minute-quota reach limit mustslower  retry next minute API 调用太频繁，请稍候再试
        /// 40013	invalid appid       请求appid身份与获取code的小程序appid不匹配
        /// </summary>
        public int errcode { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string errmsg { get; set; }

        /// <summary>
        /// 用户手机号信息
        /// </summary>
        public Phone? phone_info { get; set; }
    }

    public class Phone
    {
        /// <summary>
        /// 用户绑定的手机号（国外手机号会有区号）
        /// </summary>
        public string phoneNumber { get; set; }

        /// <summary>
        /// 没有区号的手机号
        /// </summary>
        public string purePhoneNumber { get; set; }

        /// <summary>
        /// 区号
        /// </summary>
        public string countryCode { get; set; }

        /// <summary>
        /// 数据水印
        /// </summary>
        public Watermark? watermark { get; set; }
    }
    public class Watermark
    {
        /// <summary>
        /// 用户获取手机号操作的时间戳
        /// </summary>
        public long timestamp { get; set; }

        /// <summary>
        /// 小程序appid
        /// </summary>
        public string appid { get; set; }
    }
}
